import React from 'react';
import {cn} from '@/lib/utils';

// 按钮变体类型
type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'ghost' | 'outline';

// 按钮尺寸类型
type ButtonSize = 'sm' | 'md' | 'lg' | 'icon';

// 按钮属性接口
export interface ButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {
    // 按钮变体样式
    variant?: ButtonVariant;
    // 按钮尺寸
    size?: ButtonSize;
    // 是否显示加载状态
    loading?: boolean;
    // 是否为圆形按钮
    rounded?: boolean;
    // 左侧图标
    leftIcon?: React.ReactNode;
    // 右侧图标
    rightIcon?: React.ReactNode;
    // CSS类名
    className?: string;
    // 子组件
    children?: React.ReactNode;
}

// 变体样式映射
const variantClasses: Record<ButtonVariant, string> = {
    primary: cn('btn-primary'),
    secondary: cn('btn-secondary'),
    danger: cn('btn-danger'),
    ghost: cn('bg-transparent text-gray-700 hover:bg-gray-100'),
    outline: cn('bg-transparent border border-gray-300 text-gray-700 hover:bg-gray-50'),
};

// 尺寸样式映射
const sizeClasses: Record<ButtonSize, string> = {
    sm: cn('px-3 py-1.5 text-xs'),
    md: cn('px-4 py-2 text-sm'),
    lg: cn('px-6 py-3 text-base'),
    icon: cn('p-2 w-8 h-8'),
};

// 加载动画组件
const LoadingSpinner: React.FC = () => (
    <svg
        className="animate-spin -ml-1 mr-2 h-4 w-4"
        xmlns="http://www.w3.org/2000/svg"
        fill="none"
        viewBox="0 0 24 24"
    >
        <circle
            className="opacity-25"
            cx="12"
            cy="12"
            r="10"
            stroke="currentColor"
            strokeWidth="4"
        />
        <path
            className="opacity-75"
            fill="currentColor"
            d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
        />
    </svg>
);

// 现代化按钮组件
// 支持多种变体、尺寸、状态和图标
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({
    // 解释：按钮视觉变体，默认 primary
    variant = 'primary',
    // 解释：按钮尺寸，默认 md
    size = 'md',
    // 解释：是否处于加载状态
    loading = false,
    // 解释：是否启用圆形外观
    rounded = false,
    // 解释：左侧图标节点
    leftIcon,
    // 解释：右侧图标节点
    rightIcon,
    // 解释：按钮子内容
    children,
    // 解释：额外类名
    className,
    // 解释：禁用状态（被动 + 加载）
    disabled,
    // 解释：收集剩余原生属性
    ...props
}, ref) => {
    // 解释：返回具体的按钮 JSX
    return (
        // 解释：原生 button 元素作为实际交互节点
        <button
            // 解释：向上层转发 DOM 引用，供 Tooltip/Focus 管理
            ref={ref}
            // 解释：合并 Tailwind 类名并根据状态动态拼接
            className={cn(
                // 解释：基础样式入口
                'btn',
                // 解释：变体样式映射
                variantClasses[variant],
                // 解释：尺寸样式映射
                sizeClasses[size],
                // 解释：圆角外观条件
                rounded && 'rounded-full',
                // 解释：禁用或加载态统一减弱交互
                (disabled || loading) && 'opacity-50 cursor-not-allowed',
                // 解释：自定义额外类名
                className
            )}
            // 解释：禁用属性（加载时也禁用避免重复提交）
            disabled={disabled || loading}
            // 解释：展开剩余原生属性（onClick / aria-* 等）
            {...props}
        >
            {/* 解释：左侧区域：优先显示加载动画否则显示左图标 */}
            {loading ? <LoadingSpinner/> : leftIcon}
            {/* 解释：主文本 / 子元素内容 */}
            {children}
            {/* 解释：右侧图标仅在非加载时渲染 */}
            {!loading && rightIcon}
        </button>
    );
});
// 解释：设置显示名便于 React DevTools 调试
Button.displayName = 'Button';

// 解释：IconButton 组件：在基础 Button 上封��仅图标语义，继续使用 forwardRef 保证 Tooltip 正常
export const IconButton = React.forwardRef<HTMLButtonElement, ButtonProps & {
    icon: React.ReactNode;
}>(
    // 解释：解构图标 / 子节点 / 尺寸及其余属性
    ({icon, children, size = 'icon', ...props}, ref) => (
        // 解释：复用 Button 并透传 ref 与其余属性
        <Button ref={ref} size={size} {...props}>
            {/* 解释：主图标内容 */}
            {icon}
            {/* 解释：可选的附加子内容（无文本图标按钮时可省略） */}
            {children}
        </Button>
    )
);
// 解释：设置 IconButton 显示名
IconButton.displayName = 'IconButton';
